﻿using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using QxFramework.Utilities;
//using DG.Tweening;
using UnityEngine.UI;

public class EnemyController : MonoBehaviour, IEventListener
{
    public CreatureData Data;

    public bool IsNoticed;
    //private ActionData Actions = new ActionData(); // 行动数据
    private Animator Anim;

    public NextAction CurrentAction; // 暂存行动，使用完后应置空


    private void OnEnable()
    {
        Initiate();
    }
    /// <summary>
    /// 初始化方法
    /// </summary>
    public void Initiate()
    {
        if (Data == null)
        {
            Data = GetComponent<CreatureData>();
            Data.Component = this;
        }
        if (Anim == null) Anim = GetComponent<Animator>();

        IsNoticed = false;
        Data.FlushCoordinate();
        //MapData.Instance.Registe(gameObject);
    }

    void Start()
    {
        if (EventNodeCore.GetInstance())
        {
            EventNodeCore.GetInstance().AttachEventListener(EventDef.EnemyTurn, this);
            EventNodeCore.GetInstance().AttachEventListener(-EventDef.Battle, this);
            EventNodeCore.GetInstance().AttachEventListener(EventDef.HpChange, this);
        }
    }

    private void OnDisable()
    {
        MapData.Instance.Unregiste(gameObject);
    }

    private void OnDestroy()
    {
        if (EventNodeCore.GetInstance())
        {
            EventNodeCore.GetInstance().DetachEventListener(EventDef.EnemyTurn, this);
            EventNodeCore.GetInstance().DetachEventListener(-EventDef.Battle, this);
            EventNodeCore.GetInstance().DetachEventListener(EventDef.HpChange, this);
        }
    }

    public bool HandleEvent(int id, object param1, object param2)
    {
        switch (id)
        {
            case EventDef.EnemyTurn: //行动回合
                if (CurrentAction == null)
                {
                    TrackPlayer();
                }
                Action();
                break;
            case -EventDef.Battle: //被攻击
                if ((GameObject)param2 == gameObject)
                {
                    Attacked((CreatureData)param1);
                } // 受攻击的是自己

                break;
            case EventDef.HpChange:
                if ((GameObject)param2 == gameObject)
                {
                    Data.HP += (int)param1;
                    if (Data.HP <= 0)
                    {
                        Dead();
                        EventNodeCore.GetInstance().SendMessage(EventDef.EnemyDie);
                    }
                } // Hp变动
                break;
            default:
                Debug.LogError("该行动注册但没写！" + id + " " + param1 + " " + param2);
                break;
        }
        return false;
    }

    public int EventPriority() { return 0; }

    /// <summary>
    /// 行动
    /// </summary>
    private void Action()
    {
        if (CurrentAction != null)
        {
            RegistAction(1);
            switch (CurrentAction.ActType)
            {
                case EventDef.EnemyAtk:
                    Attack();
                    break;
                case EventDef.EnemyTurnFace:
                    TurnFace();
                    break;
                case EventDef.EnemyMove:
                    MoveAct();
                    break;
                default:
                    Debug.LogError("该行动注册了但没写！");
                    break;
            }
            RegistAction(-1);
        }
        /*
         * 注册行动开始
         * 跳转至各行动
         * 行动注销由具体行动执行
         * 注销时清空CurrentAction
         */
    }
    /// <summary>
    /// 被攻击
    /// </summary>
    private void Attacked(CreatureData motherfucker)
    {
        Vector3 attackFrom = RotateBase.DirectionJudge(motherfucker.CoorDinate, Data.CoorDinate);

        {
            StartCoroutine(RotateBase.BeAttacked(gameObject, attackFrom, 0.2f, Dead));
        } // 被击中反馈

        IsNoticed = true;
        Debug.Log("敌人受到攻击");
        if (CurrentAction == null)
        {
            CurrentAction = new NextAction
            {
                MoveData = new MoveData()
            };
        }
       
        if (attackFrom == Data.Towards)
        {
            //Debug.LogError("同向" + CurrentAction);
            CurrentAction.ActType = EventDef.EnemyAtk;
            CurrentAction.AttackTarget = motherfucker.gameObject;
        } // 还击
        else
        {
            //Debug.LogError("异向" + CurrentAction);
            CurrentAction.ActType = EventDef.EnemyTurnFace;
            CurrentAction.MoveData.Type = 0;
            CurrentAction.MoveData.To = new DiceData() { GroundTowards = attackFrom };
            CurrentAction.MoveData.From = Data.CoorDinate;
            CurrentAction.MoveData.Target = gameObject;
        } // 转身
        //Anim.SetTrigger("Attacked"); // 还没有反馈动画
        /*
         * 播放被攻击动画
         * 运算反应
         */
    }
    /// <summary>
    /// 转向
    /// </summary>
    private void TurnFace()
    {
        Debug.Log("敌人转向了！");
        StartCoroutine(RotateBase.FaceTo(Data.Towards, CurrentAction.MoveData)); // 执行转动面向，并传递入移动方法委托
    }
    /// <summary>
    /// 发出攻击
    /// </summary>
    private void Attack()
    {
        Debug.Log("敌人攻击了！");
        StartCoroutine(RotateBase.AttackAnim(gameObject, Data.Towards, (float)0.2, Attacking));
    }
    /// <summary>
    /// 发出攻击信号，只由动画调用。
    /// </summary>
    public void Attacking()
    {
        Debug.Log("敌人发出攻击信号");
        //Debug.Log(Data);
        //Debug.Log(CurrentAction);
        //Debug.Log(CurrentAction.AttackTarget);
        EventNodeCore.GetInstance().HandleEvent(EventDef.Battle, Data, CurrentAction.AttackTarget);
        CurrentAction = null;
    }
    /// <summary>
    /// 移动行动
    /// </summary>
    public void MoveAct()
    {
        Debug.Log("敌人移动， movedata:" + CurrentAction.MoveData);
        MoveHero();
    }
    /// <summary>
    /// 使敌人移动
    /// </summary>
    public void MoveHero()
    {
        switch (CurrentAction.MoveData.Type)
        {
            //case 0:
            //case 2:
            //    Anim.SetTrigger("Jump");
            //    StartCoroutine(RotateBase.Turning(CurrentAction.MoveData, gameObject, (float)0.4, RegistAction, null));
            //    break;
            case 1:
                Debug.Log("MOVE tarward");
                StartCoroutine(RotateBase.MoveToward(transform.gameObject, CurrentAction.MoveData, (float)0.4));
                break;
            case 3:
                Debug.LogError("移动目标错误！");
                break;
        }
        Data.FlushCoordinate(CurrentAction.MoveData.To);
        CurrentAction = null;
    }
    /// <summary>
    /// TODO 挂了
    /// </summary>
    public void Dead()
    {
        if (Data.HP <= 0)
        {
            EventNodeCore.GetInstance().SendMessage(EventDef.EnemyDie);
            GameObject Die=EffectManager.Instance.spawnParticle(2);
            Die.transform.position = this.transform.position;
            Destroy(gameObject);
        }
    }
    /// <summary>
    /// 追踪玩家
    /// </summary>
    /// <returns></returns>
    public bool TrackPlayer()
    {
        foreach (var item in Data.CoorDinate.Surface.Dices)
        {
            if (item.Value.ObjectOfGround)
                if (item.Value.ObjectOfGround.tag == "Player")
                {
                    ActionJudge();
                    return true;
                }
        }
        return false;
    }
    /// <summary>
    /// 判断行动,只可能在同一个面上
    /// </summary>
    public bool ActionJudge()
    {
        CurrentAction = new NextAction()
        {
            MoveData = new MoveData()
        };
        if (RotateBase.Adjoin(Data.CoorDinate, PlayerManager.Instance.Data.CoorDinate))
        {
            if ((Data.CoorDinate.DiceCoordinate + Data.Towards - PlayerManager.Instance.Data.CoorDinate.DiceCoordinate).magnitude < 0.01)
            {
                CurrentAction.ActType = EventDef.EnemyAtk;
                CurrentAction.AttackTarget = PlayerManager.Instance.gameObject;
                IsNoticed = true;
                return true;
            } // 同向
            else
            {
                if (IsNoticed)
                {
                    Vector3 facingTo = RotateBase.DirectionJudge(PlayerManager.Instance.Data.CoorDinate, Data.CoorDinate);
                    CurrentAction.ActType = EventDef.EnemyTurnFace;
                    CurrentAction.MoveData.Type = 0;
                    CurrentAction.MoveData.To = new DiceData() { GroundTowards = facingTo };
                    CurrentAction.MoveData.From = Data.CoorDinate;
                    CurrentAction.MoveData.Target = gameObject;
                    return true;
                } // 转向
            } // 异向
        } // 相邻
        else
        {
            if (IsNoticed)
            {
                Vector3 facingTo = RotateBase.DirectionJudge(PlayerManager.Instance.Data.CoorDinate, Data.CoorDinate);
                Vector3 facingTo2 = RotateBase.DirectionJudgeReverse(PlayerManager.Instance.Data.CoorDinate, Data.CoorDinate);
                if ((Data.Towards - facingTo).magnitude < 0.01 || (Data.Towards - facingTo2).magnitude < 0.01)
                {
                    CurrentAction.ActType = EventDef.EnemyMove;
                    var to = new Vector3Int((int)(Data.CoorDinate.DiceCoordinate + Data.Towards).x, (int)(Data.CoorDinate.DiceCoordinate + Data.Towards).y, (int)(Data.CoorDinate.DiceCoordinate + Data.Towards).z);
                    CurrentAction.MoveData = RotateBase.MoveToJudge(Data.CoorDinate, Data.CoorDinate.Surface.Dices[to]);
                    CurrentAction.MoveData.Target = gameObject;
                    return true;
                } // 向前走一格
                else
                {
                    CurrentAction.ActType = EventDef.EnemyTurnFace;
                    CurrentAction.MoveData.Type = 0;
                    CurrentAction.MoveData.To = new DiceData() { GroundTowards = facingTo };
                    CurrentAction.MoveData.From = Data.CoorDinate;
                    CurrentAction.MoveData.Target = gameObject;
                    return true;
                } // 转向
            }
        } // 不相邻
        CurrentAction = null;
        return false;
    }
    /// <summary>
    /// 注册行动或注销
    /// </summary>
    /// <param name="IsR">1为注册，-1为注销</param>
    private void RegistAction(int IsR)
    {
        EventNodeCore.GetInstance().HandleEvent(EventDef.Action * IsR, null, null);
    }
    /// <summary>
    /// 行动数据
    /// </summary>
    private class ActionData
    {
        private Dictionary<int, Queue<NextAction>> Things2Do = new Dictionary<int, Queue<NextAction>>(); // 作用是有优先级的行为逻辑,同等优先级先注册先执行,越小越先,最小为0最大为10

        public bool RegisteAction(NextAction act, int priority)
        {
            if (priority >= 0 && priority <= 10)
            {
                if (!Things2Do.ContainsKey(priority))
                {
                    Things2Do.Add(priority, new Queue<NextAction>());
                }
                Things2Do[priority].Enqueue(act);
                return true;
            }
            else return false;
        }

        public NextAction GetAcion()
        {
            for (int i = 0; i <= 10; i++)
            {
                if (Things2Do.ContainsKey(i))
                {
                    return Things2Do[i].Dequeue();
                }
            }
            return null;
        }
    }
}
